package com.corner.presenter.imp;

import android.database.Cursor;

import com.corner.app.App;
import com.corner.model.db.DBConstans;
import com.corner.model.db.Session;
import com.corner.model.db.SessionDao;
import com.corner.presenter.ISessionPresenter;
import com.corner.presenter.base.BasePresenter;
import com.corner.ui.view.ISessionView;
import com.corner.utils.CollectionUtil;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Observer;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * Created by Administrator on 2015/7/12，22.08.
 * 描述：
 */
public class SessionPresenter extends BasePresenter<ISessionView> implements ISessionPresenter, Observer {
    public static final Integer PAGE_MESSAGE_SIZE = 10;
    public static final String SQL = "select * from %s where %s in (select max(%s) from %s group by %s)  group by %s order by %s desc limit %s";
    private List<Session> sessions;
    /**
     * 是否有更多的消息
     */
    private boolean hasMore = true;
    private boolean isLoading = false;
    private Date timestampOfLastItem;
    private final String tablename;
    private final String timestampColumnName;
    private final String sessionNameColumnName;
    private final String typeColumnName;

    public SessionPresenter() {
        if (App.application.daoSession==null){
            App.application.initSession();
        }
        App.application.daoSession.getSessionDao().addObserver(SessionPresenter.this);
        tablename = App.application.daoSession.getSessionDao().getTablename();
        timestampColumnName = SessionDao.Properties.Timestamp.columnName;
        sessionNameColumnName = SessionDao.Properties.SessionName.columnName;
        typeColumnName = SessionDao.Properties.Type.columnName;
    }

    @Override
    public void refresh() {
        Observable.create(new Observable.OnSubscribe<List<Session>>() {
            @Override
            public void call(Subscriber<? super List<Session>> subscriber) {
                hasMore = true;

                if (timestampOfLastItem == null) {
                    String sessionSizeToShow = PAGE_MESSAGE_SIZE.toString();
                    Cursor cursor =  App.application.daoSession.getSessionDao().getDatabase()
                            .rawQuery(String.format(SQL, tablename, timestampColumnName,
                                    timestampColumnName, tablename, sessionNameColumnName,
                                             sessionNameColumnName, timestampColumnName,
                                            sessionSizeToShow), null);
                    sessions = App.application.daoSession.getSessionDao().cursorToList(cursor);
                    cursor.close();
                    if (sessions!=null&&sessions.size() < PAGE_MESSAGE_SIZE) {
                        hasMore = false;
                    }
                }else{
                    String sessionSizeToShow = String.valueOf(sessions.size() > PAGE_MESSAGE_SIZE ? sessions.size() : PAGE_MESSAGE_SIZE);
                    Cursor cursor =  App.application.daoSession.getSessionDao().getDatabase()
                            .rawQuery(String.format(SQL, tablename, timestampColumnName,
                                            timestampColumnName, tablename, sessionNameColumnName,
                                            sessionNameColumnName, timestampColumnName,
                                            sessionSizeToShow), null);
                    sessions = App.application.daoSession.getSessionDao().cursorToList(cursor);
                    cursor.close();
                }
                if (sessions != null) {
                    if (sessions.size() > 0) {
                        timestampOfLastItem = sessions.get(sessions.size() - 1).getTimestamp();
                    }
                }
                subscriber.onNext(sessions);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
                .subscribe(new Subscriber<List<Session>>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (view != null) {
                            view.refreshComplete();
                        }
                    }

                    @Override
                    public void onNext(List<Session> sessions) {
                        if (view != null) {
                            view.refreshComplete();
                            if (!hasMore) {
                                view.setLoadMoreEnable(false);
                            }
                            view.showRefreshSession(sessions);
                            checkNotReadedSession();
                        }
                    }
                });
    }

    @Override
    public void loadMore() {
        if (!hasMore || sessions == null) {
            view.loadMoreComplete();
            return;
        }
        if (isLoading) {
            return;
        }
        isLoading = true;
        Observable.create(new Observable.OnSubscribe<List<Session>>() {
            @Override
            public void call(Subscriber<? super List<Session>> subscriber) {
                int sessionCountBeforeLoadMore = sessions.size();

                //获取最后一条记录的时间之前的记录
                String sessionSizeToShow = String.valueOf(PAGE_MESSAGE_SIZE + sessions.size());
                Cursor cursor =  App.application.daoSession.getSessionDao().getDatabase()
                        .rawQuery(String.format(SQL, tablename, timestampColumnName,
                                        timestampColumnName, tablename, sessionNameColumnName,
                                        sessionNameColumnName, timestampColumnName,
                                        sessionSizeToShow), null);
                sessions = App.application.daoSession.getSessionDao().cursorToList(cursor);
                cursor.close();
                if (CollectionUtil.isCollectionEmpty(sessions)) {
                    hasMore = false;
                } else {
                    if (sessions.size() <= sessionCountBeforeLoadMore) {
                        hasMore = false;
                    }
                    subscriber.onNext(sessions);
                }
                subscriber.onCompleted();
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
                .subscribe(new Subscriber<List<Session>>() {
                    @Override
                    public void onCompleted() {
                        if (view != null) {
                            view.loadMoreComplete();
                            if (!hasMore) {
                                view.setLoadMoreEnable(false);
                            }
                            isLoading = false;
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (view != null) {
                            view.loadMoreComplete();
                            isLoading = false;
                        }
                    }

                    @Override
                    public void onNext(List<Session> sessions) {
                        if (view != null) {
                            view.showLoadMoreSession(sessions);
                            checkNotReadedSession();
                            isLoading = false;
                        }
                    }
                });
    }

    @Override
    public void checkNotify() {
        Observable.create(new Observable.OnSubscribe<Boolean>() {
            @Override
            public void call(Subscriber<? super Boolean> subscriber) {
                long count = App.application.daoSession.getSessionDao().queryBuilder().where(
                        SessionDao.Properties.Type.eq(DBConstans.LIKE),SessionDao
                        .Properties.IsReaded.eq(false)).limit(1).buildCount().count();
//                Cursor cursor = App.application.daoSession.getSessionDao()
//                        .getDatabase().query(App.application.daoSession.getSessionDao()
//                                        .getTablename(), null, SessionDao.Properties.Type.columnName + " = ? and "
//                                        + SessionDao.Properties.IsReaded.columnName + " = ? ",
//                                new String[]{DBConstans.LIKE, DBConstans.FALSE},
//                                SessionDao.Properties.SessionName.columnName, null,
//                                SessionDao.Properties.Timestamp.columnName + " desc", "1");
//                cursor.close();
//                if (sessions != null && sessions.size() != 0) {
//                    subscriber.onNext(true);
//                } else {
//                    subscriber.onNext(false);
//                }
                if (count>0){
                    subscriber.onNext(true);
                }else {
                    subscriber.onNext(false);
                }

            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean hasNotify) {
                if (view != null) view.showHasNotify(hasNotify);
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {

            }
        });
    }

    @Override
    public void checkNotReadedSession() {
        Observable.create(new Observable.OnSubscribe<Boolean>() {
            @Override
            public void call(Subscriber<? super Boolean> subscriber) {
//                Cursor cursor = App.application.daoSession.getSessionDao().getDatabase()
//                        .query(App.application.daoSession.getSessionDao().getTablename(),null,
//                        SessionDao.Properties.Type.columnName + " != ? and "
//                                + SessionDao.Properties.IsReaded.columnName + " = ? ",
//                        new String[]{DBConstans.LIKE, DBConstans.FALSE},
//                                SessionDao.Properties.SessionName.columnName, null, SessionDao.Properties.Timestamp.columnName + " desc", "1");
//                List<Session> likes = App.application.daoSession.getSessionDao().cursorToList(cursor);
//                cursor.close();
//                if (likes != null && likes.size() != 0) {
//                    subscriber.onNext(true);
//                } else {
//                    subscriber.onNext(false);
//                }
                boolean hasNotReadedSession = false;
                if (!CollectionUtil.isCollectionEmpty(sessions)) {
                    hasNotReadedSession = isHasNotReadedSessionInSessions(sessions);
                }
                subscriber.onNext(hasNotReadedSession);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean o) {
                if (view != null) view.showHasNotReadedSession(o);
            }
        });
    }

    /**
     * 在session中寻找是否有未读消息
     * @param sessions
     * @return
     */
    private boolean isHasNotReadedSessionInSessions(List<Session> sessions) {
        for (Session session : this.sessions) {
            if (!session.getIsReaded()) {
                return true;
            }
        }
        return false;
    }


    @Override
    public void update(java.util.Observable observable, Object data) {
        Map<String, Object> map = (Map<String, Object>) data;
        SessionDao.SessionOperate item = (SessionDao.SessionOperate) map.get(SessionDao.SESSION_OPERATE);
        switch (item) {
            case READ:
                refresh();
                checkNotify();
                break;
            case INSERT:
                refresh();
                checkNotify();
                break;
            case DELETE:
                refresh();
                break;
            case UPDATE:
                break;
            case INSERT_BATCH:
                refresh();
                break;
            case DELETE_BATCH:
                refresh();
                break;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (App.application.daoSession != null) {
            App.application.daoSession.getSessionDao().deleteObserver(this);
        }
    }
}
